/*
 * Copyright (c) 2017-present, CV4J Contributors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.cv4j.core.filters;

import com.cv4j.core.datamodel.ImageProcessor;
import com.cv4j.image.util.Tools;

import java.util.Optional;

/**
 * 高斯噪声滤波器
 * 随机噪声滤镜
 *
 * @author dev
 * @date 2021/07/22
 */
public class GaussianNoiseFilter extends BaseFilter {
    private int sigma;

    /**
     * 高斯噪声滤波器
     */
    public GaussianNoiseFilter() {
        sigma = 25;
    }

    /**
     * 得到σ
     *
     * @return int
     */
    public int getSigma() {
        return sigma;
    }

    /**
     * 设置σ
     *
     * @param sigma σ
     */
    public void setSigma(int sigma) {
        this.sigma = sigma;
    }

    /**
     * 做的过滤器
     *
     * @param src src
     * @return {@link ImageProcessor}
     */
    public Optional<ImageProcessor> doFilter(ImageProcessor src) {
        int red = 0;
        int greed = 0;
        int blue = 0;
        int offset = 0;
        int total = width * height;
        java.util.Random random = new java.util.Random();
        for (int i1 = 0; i1 < total; i1++) {
            red = RED[i1] & 0xff;
            greed = GREED[i1] & 0xff;
            blue = BLUE[i1] & 0xff;

            // add Gaussian noise
            red = (int) (red + sigma * random.nextGaussian());
            greed = (int) (greed + sigma * random.nextGaussian());
            blue = (int) (blue + sigma * random.nextGaussian());

            RED[i1] = (byte) Tools.clamp(red);
            GREED[i1] = (byte) Tools.clamp(greed);
            BLUE[i1] = (byte) Tools.clamp(blue);
        }
        return Optional.ofNullable(src);
    }
}
